package com.dude.utils;

import java.util.ArrayList;

import com.dude.R;
import com.dude.interfaces.IMemoryService;
import com.dude.objects.GenericPair;
import com.dude.screens.ScreensUtility;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.LinearLayout.LayoutParams;

/* this class includes methods that are needed in more than one other class, and pertain to
 * the display of dialogs.
 */
public class DialogsLibrary {
	
	private Activity activity;
	private boolean isSingle;
	
	public DialogsLibrary(Activity context, boolean isSingle)
	{
		this.activity=context;
		this.isSingle=isSingle;
	}
	
	
    /* this method opens a dialog asking the user if he is sure he wants to delete the object. 
     * if he is sure, the object is deleted from the memory.
     */
    public void deleteObjectDialog(final String objectName, final IMemoryService fo)
    {
    	AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    	builder.setTitle("Delete Object Dialog");
    	builder.setMessage("Are you sure you want to delete the object and all it's data from memory?");
    	builder.setCancelable(true);
    	builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				if (!fo.removeObject(objectName, isSingle))
					createErrorDialog("Deleting Object Failed");
				activity.finish();
				dialog.dismiss();				
			}
		  });
    	builder.setNegativeButton("No",new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				dialog.cancel();
			}
		});
    	
    	//create the dialog
    	AlertDialog dialog = builder.create();
    	dialog.show(); 	
    }

    
    
    /* the method shows an alarm dialog with msg explaining the error
     * 
     */
    public void createErrorDialog(String msg)
    {
    	AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    	builder.setTitle("Error ");
    	builder.setMessage(msg);
    	builder.setCancelable(true);
    	builder.setPositiveButton(" OK ", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				dialog.cancel();			
			}
		  });
    	
    	//create the dialog
    	AlertDialog dialog = builder.create();
    	dialog.show();
    	Button btn = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);
    	btn.setBackgroundResource(R.drawable.button_blue);   
    }
    

    /* the method displays a dialog for the addition of a new comment
     */
    public void AddCommentDialog(final String objectName, final IMemoryService fo,
    					final ArrayList<String> commentsList, final ArrayAdapter<String> arrayAdapter,
    									final ListView commentsListView)
    {       	
    	//create the dialog
    	final Dialog dialog = new Dialog(activity);    	
    	dialog.setContentView(R.layout.general_dialog);
		dialog.setTitle(" Add Comment ");
		dialog.setCancelable(true);
		
		// prepare the text fields
		final EditText editText = (EditText)dialog.findViewById(R.id.dialogET);
		editText.setHint("type in the comment: ");
							
		//prepare the buttons - cancel and edit		
		Button saveButton = (Button)dialog.findViewById(R.id.setButton);
		saveButton.setText(" save comment ");
		Button cancelButton = (Button)dialog.findViewById(R.id.cancelButton);
		saveButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {					
					String newComment = editText.getText().toString();	
					if (newComment.trim().equals(""))	//don't add empty comment
					{
						dialog.dismiss();
						return;					
					}						
					// commit comment to memory - add new comment
					if (!fo.addCommentForObject(objectName, isSingle, newComment))
					{
						createErrorDialog(" Adding comment failed ");
						dialog.dismiss();
						return;
					}
					// change public list of comments
					// ------------------warning: posInList may be wrong index!!!------					 
					commentsList.add(newComment);
					arrayAdapter.notifyDataSetChanged();						
					ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);					
					dialog.dismiss();
				}				
		 });
			
		 cancelButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					dialog.dismiss();						
				}				
		 });
		 
    	dialog.show();
    }

  
    /* the method displays a dialog where the user can edit a comment 
     *    
     */
    public void editCommentDialog(final String objectName, final IMemoryService fo,
					final ArrayList<String> commentsList, final ArrayAdapter<String> arrayAdapter,
					final String oldComment, final int posInList, final ListView commentsListView)
    {   	
    	//create the dialog
    	final Dialog dialog = new Dialog(activity);
		dialog.setContentView(R.layout.general_dialog);
		dialog.setTitle(" Edit Comment ");
		dialog.setCancelable(true);
		
		// prepare the text fields
		final EditText editText = (EditText)dialog.findViewById(R.id.dialogET);
		editText.setText(oldComment);
		editText.setHint("edit the comment");
							
		//prepare the buttons - cancel and edit		
		Button editButton = (Button)dialog.findViewById(R.id.setButton);
		editButton.setText(" save changes to comment ");
		Button cancelButton = (Button)dialog.findViewById(R.id.cancelButton);
		editButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {					
					String newComment = editText.getText().toString();
					if (newComment.trim().equals(""))	//if it's empty - delete the old comment
					{
						if (!fo.removeComment(objectName, isSingle, oldComment))
						{
							createErrorDialog(" Editing comment failed ");
							dialog.dismiss();
							return;
						}
						commentsList.remove(posInList); 
						arrayAdapter.notifyDataSetChanged();					
						ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);
						dialog.dismiss();
						return;					
					}
					// commit comment to memory - call to delete for old comment and add for new comment
					if (!fo.removeComment(objectName, isSingle, oldComment))
					{
						createErrorDialog(" Editing comment failed ");
						dialog.dismiss();
						return;
					}
					if (!fo.addCommentForObject(objectName, isSingle, newComment))
					{
						createErrorDialog(" Editing comment failed ");
						dialog.dismiss();
						return;
					}
					// change public list of comments
					// ------------------warning: posInList may be wrong index!!!------
					commentsList.remove(posInList); 
					commentsList.add(newComment);
					arrayAdapter.notifyDataSetChanged();					
					ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);					
					dialog.dismiss();
				}				
		 });
			
		 cancelButton.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					dialog.dismiss();						
				}				
		 });
		
		// add additional button to LinearLayout
		LinearLayout ll = (LinearLayout)dialog.findViewById(R.id.buttonsLayout);
		//add delete button
		Button deleteButton = new Button(activity);
		deleteButton.setText(" delete current comment ");
		deleteButton.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
		deleteButton.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				// delete comment from memory
				if (!fo.removeComment(objectName, isSingle, oldComment))
				{
					createErrorDialog(" Editing comment failed ");
					dialog.dismiss();
					return;
				}
				// delete comment from public list of comments 
				// ------------------warning: posInList may be wrong index!!!------
				commentsList.remove(posInList);
				arrayAdapter.notifyDataSetChanged();				
				ScreensUtility.setListViewHeightBasedOnChildren(commentsListView);							
				dialog.dismiss();
			}				
		});
		ll.addView(deleteButton);		

    	dialog.show();
    }
    
         
    /* the method displays a dialog explaining that operation couldn't be carried out because
     * object easn't given a name yet
     */
    public void createOperationDeniedDialog(String msg)
    {
    	AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    	builder.setTitle("Requested Operation Denied ");
    	builder.setMessage(msg);
    	builder.setCancelable(true);
    	builder.setPositiveButton(" OK ", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int id) {
				dialog.cancel();			
			}
		  });
    	
    	//create the dialog
    	AlertDialog dialog = builder.create();
    	dialog.show();  
    }
    
    
    /* the method displays a dialog where the user can give a new object a name/ edit the name
     * of existing object
     * at the end input parameter result includes the new name if one was given or null otherwise,
     * and true/false if the name change succeeded/ failed or was canceled.
     * 
     * call objectName.setText(name);	 after call to this method
     * 
     */
    public Dialog createNameDialog(boolean objectHasName, final boolean existingProfile,
    									final String name, final IMemoryService fo, 
    									final GenericPair<String, Boolean> result)
    {
    	//create the dialog
    	final Dialog dialog = new Dialog(activity);
		dialog.setContentView(R.layout.general_dialog);
		dialog.setTitle("Change The Object's Name");
		dialog.setCancelable(true);
		
		//prepare the text fields
		final EditText editName = (EditText)dialog.findViewById(R.id.dialogET);
		if (objectHasName)				
			editName.setText(name);
		else
			editName.setHint("type object name here");		
						
		Button setButton = (Button)dialog.findViewById(R.id.setButton);
		Button cancelButton = (Button)dialog.findViewById(R.id.cancelButton);
		
		setButton.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				String newName = editName.getText().toString();				
				if (existingProfile)
				{
					if (name.equals(newName))
					{												
						result.setFirst(null);
						result.setSecond(false);	
						dialog.dismiss();
						return;
					}
					String str = changeObjectName(name, newName, fo);
					if (str!=null)
					{
						result.setFirst(null);
						result.setSecond(false);						
						createErrorDialog(str);
						dialog.dismiss();
						return;
					}					
					else
					{
						result.setFirst(newName);
						result.setSecond(true);
					}											
				}
				else
				{
					int success = fo.addObject(newName, isSingle);
					if (success==2)
					{
						result.setFirst(null);
						result.setSecond(false);	
						createErrorDialog(" Error - object with same name already exists ");
						dialog.dismiss();
						return;
					}
					if (success==3)
					{
						result.setFirst(null);
						result.setSecond(false);	
						createErrorDialog(" Error - creating profile failed ");
						dialog.dismiss();
						return;
					}	
					result.setFirst(newName);
					result.setSecond(true);				
				}
				dialog.dismiss();
			}				
		});
		
		cancelButton.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				result.setFirst(null);
				result.setSecond(false);	
				dialog.dismiss();						
			}				
		});
		return dialog;		  
    }
    
    
    //=======================================================================================
    //========================== additional methods: ============================
    //=======================================================================================
    
    
    /* the method applies change of name for current object, including memory update. 
     * if the operation is successful it returns null, else it returns a string describing
     * the error (and the object's name doesn't change)
     * -- assumes object already exists in memory with name olsName
     */
    protected String changeObjectName(String oldName, String newName, final IMemoryService fo)
    {
    	if (newName==null)
    		return "No Name Was Given For Object ";
    	// remove leading and trailing white spaces
    	newName = newName.trim();
    	// check that the new name has at least one alpha numeric character in it (and isn'r empty)
    	if (!newName.matches(".*\\w.*"))
    		return "The Name Must Include At Least One Alpha Numeric Character ";
    	// check no other object with this name already exists
    	if (isSingle)
    	{
        	if (!fo.isNameFreeForSingleObject(newName))
        		return "An Object With Name ["+newName+"]Already Exists ";
        	// if reached this point - the new name is valid
        	
        	Log.i("dialog library ", "change object name - before trying to change name with fo");
        	
        	if (!fo.renameSingleObject(oldName, newName))
        		return " error Renaming object failed ";       	
    	}
    	else
    	{
        	if (!fo.isNameFreeForMultiObject(newName))
        		return "A Multi Object With Name ["+newName+"]Already Exists ";
        	// if reached this point - the new name is valid
        	if (!fo.renameMultiObject(oldName, newName))
        		return " error Renaming object failed ";      	
    	}
    	
    	return null;
    }
      
    
    
}
